package com.ctgu.tengyun.util;

import com.ctgu.tengyun.bean.TokenBean;
import com.ctgu.tengyun.domain.SysUser;
import com.ctgu.tengyun.exception.UnAuthorizedException;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

public class RequestExtract {

    private static final String AUTH_KEY = "__UserAuth";

    public static final String KEY_AUTH_TOKEN = "token";
    public static final String SESSION = "si";
    public static final String SIGN = "sg";

    public static final String HEADER_TIMESTAMP = "Timestamp";
    public static final String HEADER_AUTHKEY = "Authkey";

    public static final String APP_PLATFORM = "appplatform";
    public static final String APP_NAME = "appname";
    public static final String APP_VERSION = "appversion";
    public static final String QQUID = "qquid";
    public static final String GUID = "guid";

    private static final String USER_AGENT = "User-Agent";
    private static final String USERIP = "UserIp";

    public static final String RESP_BUILDER = "resp_builder";

    private static final Charset CHARSET = Charset.forName("UTF-8");

    public static String getHttpUserAgent(HttpServletRequest request) {
        return request.getHeader(USER_AGENT);
    }

    public static String getAppPlatform(HttpServletRequest request) {
        return ParameterTool.getParameterString(request, APP_PLATFORM, "");
    }

    public static String getAppName(HttpServletRequest request) {
        return ParameterTool.getParameterString(request, APP_NAME, "");
    }

    public static String getAppVersion(HttpServletRequest request) {
        return ParameterTool.getParameterString(request, APP_VERSION, "");
    }

    public static String getQqUid(HttpServletRequest request) {
        return ParameterTool.getParameterString(request, QQUID, "");
    }

    public static String getGuid(HttpServletRequest request) {
        return ParameterTool.getParameterString(request, GUID, "");
    }

    public static boolean isQingQingDebug(HttpServletRequest request) {
        String mode = ParameterTool.getParameterString(request, ParameterTool.DEBUG_MODE, null);
        if (StringUtils.isEmpty(mode)) {
            mode = request.getHeader(ParameterTool.DEBUG_MODE);
        }

        return ParameterTool.TURNON_DEBUG_MODE.equals(mode);
    }

    public static long getHeaderTimestamp(HttpServletRequest request) {
        long defaultValue = -1l;
        String value = getHeaderValue(request, HEADER_TIMESTAMP, String.valueOf(defaultValue));
        try {
            return Long.parseLong(value);
        } catch (Exception ignore) {
        }
        return defaultValue;
    }

    public static String getHeaderAuthKey(HttpServletRequest request) {
        return getHeaderValue(request, HEADER_AUTHKEY, null);
    }

    public static String getHeaderValue(HttpServletRequest request, String name, String defaultValue) {
        String value = request.getHeader(name);
        if (value == null) {
            return defaultValue;
        }

        return value;
    }

    public static String getToken(HttpServletRequest request) {
        String token = ParameterTool.getParameterString(request, KEY_AUTH_TOKEN, null);
        if (StringUtils.isEmpty(token)) {
            token = request.getHeader(KEY_AUTH_TOKEN);
        }
        return token;
    }

    public static String getSession(HttpServletRequest request) {
        String session = ParameterTool.getParameterString(request, SESSION, null);
        if (StringUtils.isEmpty(session)) {
            session = request.getHeader(SESSION);
        }
        return session;
    }

    public static String getSign(HttpServletRequest request) {
        String sign = ParameterTool.getParameterString(request, SIGN, null);
        if (StringUtils.isEmpty(sign)) {
            sign = request.getHeader(SIGN);
        }
        return sign;
    }

    public static void setRequestUser(HttpServletRequest request, TokenBean tokenBean) {
        request.setAttribute(AUTH_KEY, tokenBean);
    }

    public static Long getUserId(HttpServletRequest request){
        return getTokenBeanWithAuthValidate(request).getUserId();
    }

    public static TokenBean getTokenBeanWithAuthValidate(HttpServletRequest request) {
        TokenBean tokenBean = (TokenBean) request.getAttribute(AUTH_KEY);
        if (null == tokenBean) {
            throw new UnAuthorizedException("no user founded", "parameter missed");
        } else {
            return tokenBean;
        }
    }

    public static SysUser getUserWithAuthValidate(HttpServletRequest request) {
        SysUser user = (SysUser) request.getAttribute(AUTH_KEY);
        if (null == user) {
            throw new UnAuthorizedException("no user founded", "parameter missed");
        } else {
            return user;
        }
    }

    public static final Map<String, String> getHttpRequestParameters(HttpServletRequest httpRequest) {
        Map<String, String[]> raw_parameters = httpRequest.getParameterMap();
        Map<String, String> map = new HashMap<String, String>(raw_parameters.size());
        for (Map.Entry<String, String[]> entry : raw_parameters.entrySet()) {
            String key = entry.getKey();
            String[] obj = entry.getValue();
            String value = "";
            for (int i = 0; i < obj.length; i++) {
                value = obj[i] + ",";
            }
            value = value.substring(0, value.length() - 1);
            map.put(key, value);
        }
        return map;
    }

    public static String readStringFromRequest(HttpServletRequest request, Charset charset) {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(request.getInputStream(), charset));

            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            return sb.toString();
        } catch (IOException e) {
            throw new RuntimeException("read body failed", e);
        } finally {
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                }
            }
        }
    }

    public static String readBodyFromRequest(HttpServletRequest request) {
        return readStringFromRequest(request, CHARSET);
    }

    public static String getServerIpByRequest(HttpServletRequest request) {
        String fromHost = request.getHeader("X-Real-IP");
        if (null == fromHost || fromHost.isEmpty()) {
            fromHost = request.getRemoteHost();
        }
        return fromHost;
    }
}
